package com.quanquan.store.service.marketActivity;

import DTO.PageDTO;
import DTO.user.UserDTO;
import DTO.user.UserInfoDTO;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.quanquan.store.dto.CouponDTO;
import com.quanquan.store.dto.IdDTO;
import com.quanquan.store.entity.marketActivity.MaRedisConstant;
import com.quanquan.store.entity.marketActivity.turnTable.*;
import com.quanquan.store.repository.marketActivity.turnTable.*;
import com.quanquan.store.request.marketActivity.TurnTableRequest;
import com.quanquan.store.service.CouponService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.*;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import utils.StringUtils;

import javax.persistence.criteria.Predicate;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @ClassName TurnTableService
 * @Description
 * @Author Owen
 * @Date 2019/9/19 0019 上午 10:37
 * @Version V1.0
 **/
@Service
@Slf4j
public class TurnTableService {

    @Autowired
    private TurnTableRepository turnTableRepository;

    @Autowired
    private TurnTableChanceRepository turnTableChanceRepository;

    @Autowired
    private TurnTableGiftRepository turnTableGiftRepository;

    @Autowired
    private TurnTableRecordRepository turnTableRecordRepository;

    @Autowired
    private TurnTableChanceRecordRepository turnTableChanceRecordRepository;

    @Autowired
    private CouponService couponService;

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 根据ID查询活动信息
     * @param id
     * @return
     */
    public TurnTable getById(Long id){

        TurnTable turnTable = null;

        //获取redis缓存
        String infoKey = String.format(MaRedisConstant.TURN_TABLE_INFO,id);
        if(redisTemplate.hasKey(infoKey)){
            turnTable = (TurnTable) redisTemplate.opsForValue().get(infoKey);
        }else{
            turnTable = turnTableRepository.findById(id).orElse(null);
            if (null == turnTable) {
                return null;
            }
            //活动信息缓存redis
            redisTemplate.opsForValue().set(infoKey,turnTable,MaRedisConstant.TURN_TABLE_INFO_EXPRISE_DAYS, TimeUnit.DAYS);
        }

        return turnTable;
    }

    public TurnTable saveOrUpdateTurnTable(TurnTable turnTable){

        turnTable = turnTableRepository.saveAndFlush(turnTable);

        String infoKey = String.format(MaRedisConstant.TURN_TABLE_INFO,turnTable.getId());
        if(redisTemplate.hasKey(infoKey)){
            redisTemplate.opsForValue().set(infoKey,turnTable);
        }else{
            redisTemplate.opsForValue().set(infoKey,turnTable,MaRedisConstant.TURN_TABLE_INFO_EXPRISE_DAYS, TimeUnit.DAYS);
        }

        return turnTable;
    }

    public TurnTableGift saveOrUpdateGift(TurnTableGift turnTableGift){
        return turnTableGiftRepository.saveAndFlush(turnTableGift);
    }

    /**
     * 获取用户活动机会
     * @param activityId
     * @param userId
     * @return
     */
    public TurnTableChance getByIdAndUserId(Long activityId, String userId){

        TurnTableChance turnTableChance;

        //获取redis缓存
        String infoKey = String.format(MaRedisConstant.TURN_TABLE_CHANCE_INFO,activityId,userId);
        if(redisTemplate.hasKey(infoKey)){
            turnTableChance = (TurnTableChance) redisTemplate.opsForValue().get(infoKey);
        }else{
            turnTableChance = new TurnTableChance();
            turnTableChance.setUserId(userId);
            turnTableChance.setActivityId(activityId);
            Example<TurnTableChance> example = Example.of(turnTableChance);
            turnTableChance = turnTableChanceRepository.findOne(example).orElse(null);
            if (null == turnTableChance) {
                turnTableChance = this.addUserChance(activityId,userId);
            }
        }

        if(!DateUtil.isSameDay(turnTableChance.getUpdateTime(),new Date())){
            turnTableChance.setChance(1);
            turnTableChance.setUpdateTime(new Date());
            turnTableChance = this.saveOrUpdateChance(turnTableChance);
        }

        return turnTableChance;
    }

    /**
     * 获取活动所有可用奖品列表(前端显示)
     * @param activityId
     * @return
     */
    public List<TurnTableGift> getGiftsByActivityId(Long activityId, Integer activityType){
        List<TurnTableGift> giftList = turnTableGiftRepository.findAllByActivityIdAndActivityTypeAndStatusAndStartTimeBeforeAndEndTimeAfterOrderByGiftIndexAsc(activityId,activityType, 1, new Date(), new Date());
        return giftList;
    }
    public List<TurnTableGift> getGiftsByActivityIdForGame(Long activityId){
        List<TurnTableGift> giftList = turnTableGiftRepository.findAllByActivityIdAndStatusAndStartTimeBeforeAndEndTimeAfterAndRemainTotalGreaterThan(activityId, 1, new Date(), new Date(),0);
        return giftList;
    }

    /**
     * 根据活动id获取活动所有有效奖项总概率
     * @param activityId
     * @return
     */
    public Integer sumGiftOdds(Long activityId){
        Integer sumOdds = turnTableGiftRepository.findSumOdds(activityId);
        if(null == sumOdds){
            return 0;
        }else{
            return sumOdds;
        }
    }

    public TurnTableGift getOneNoGift(Long activityId){
        TurnTableGift gift = turnTableGiftRepository.findFirstByActivityIdAndStatusAndStartTimeBeforeAndEndTimeAfterAndGiftType(activityId, 1, new Date(), new Date(), 0);
        return gift;
    }

    public TurnTableChance saveOrUpdateChance(TurnTableChance turnTableChance){

        turnTableChance = turnTableChanceRepository.saveAndFlush(turnTableChance);

        String infoKey = String.format(MaRedisConstant.TURN_TABLE_CHANCE_INFO,turnTableChance.getActivityId(),turnTableChance.getUserId());
        if(redisTemplate.hasKey(infoKey)) {
            redisTemplate.opsForValue().set(infoKey,turnTableChance);
        }else{
            //获取当天23:59:59时间
            LocalDateTime midnight = LocalDateTime.now()
                    .plusDays(1)
                    .withHour(0).withMinute(0).withSecond(0).withNano(0)
                    .minusSeconds(1);
            long seconds = ChronoUnit.SECONDS.between(LocalDateTime.now(), midnight);

            redisTemplate.opsForValue().set(infoKey,turnTableChance,seconds, TimeUnit.SECONDS);
        }

        return turnTableChance;
    }

    public TurnTableRecord saveOrUpdateRecord(TurnTableRecord turnTableRecord){
        turnTableRecord = turnTableRecordRepository.saveAndFlush(turnTableRecord);
        return turnTableRecord;
    }

    /**
     * 扣将活动奖项剩余库存
     * @param giftId
     * @return
     */
    public int substractGiftStock(Long giftId){
        int stock = turnTableGiftRepository.substractStock(giftId);
        return stock;
    }

    public List<TurnTableRecord> getTurnRecordList(Long activityId, Integer activityType, Integer page, Integer size){
        return turnTableRecordRepository.findAllRecords(activityId,activityType,page*size,size);
    }

    public TurnTableGift getByGiftId(Long giftId){
        TurnTableGift turnTableGift = turnTableGiftRepository.findById(giftId).orElse(null);
        return turnTableGift;
    }

    public List<TurnTableChanceRecord> getChanceRecordByConsumId(String consumId){

        TurnTableChanceRecord turnTableChanceRecord = new TurnTableChanceRecord();
        turnTableChanceRecord.setConsumeId(consumId);
        Example<TurnTableChanceRecord> example = Example.of(turnTableChanceRecord);
        List<TurnTableChanceRecord> all = turnTableChanceRecordRepository.findAll(example);
        return all;
    }

    public void saveOrUpdateChanceRecord(TurnTableChanceRecord turnTableChanceRecord){
        turnTableChanceRecordRepository.saveAndFlush(turnTableChanceRecord);
    }

    public TurnTableChance addUserChance(Long activityId, String userId){
        TurnTableChance turnTableChance = new TurnTableChance();
        turnTableChance.setUserId(userId);
        turnTableChance.setActivityId(activityId);
        Example<TurnTableChance> example = Example.of(turnTableChance);
        turnTableChance = turnTableChanceRepository.findOne(example).orElse(null);
        if(null == turnTableChance){
            turnTableChance = new TurnTableChance();
            turnTableChance.setUserId(userId);
            turnTableChance.setActivityId(activityId);
            turnTableChance.setChance(1);
            turnTableChance.setCreateTime(new Date());
            turnTableChance.setUpdateTime(new Date());
        }else{
            turnTableChance.setChance(turnTableChance.getChance() + 1);
        }

        return this.saveOrUpdateChance(turnTableChance);
    }

    public List<TurnTableRecord> getBigRecordByHour(long activityId, int hour){
        TurnTableRecord record = new TurnTableRecord();
        record.setActivityType(2);
        record.setActivityId(activityId);
        record.setTimeIndex(hour);
        Example<TurnTableRecord> example = Example.of(record);
        List<TurnTableRecord> all = turnTableRecordRepository.findAll(example);
        return all;
    }

    public List<TurnTableGift> getBigGiftByHour(long activityId, int hour){
        TurnTableGift gift = new TurnTableGift();
        gift.setActivityId(activityId);
        gift.setActivityType(2);
        gift.setGiftIndex(hour);
        Example<TurnTableGift> example = Example.of(gift);
        List<TurnTableGift> all = turnTableGiftRepository.findAll(example);
        return all;
    }

    public List<TurnTableRecord> getTurnRecordForBig(long activityId){
        List<TurnTableRecord> list = turnTableRecordRepository.findDistinctByUserIdAndActivityId(activityId);
        return list;
    }

    public List<TurnTableRecord> getTurnRecordByUserIdAndActivityType(String userId, Long activityId, Integer activityType){
        TurnTableRecord record = new TurnTableRecord();
        record.setActivityId(activityId);
        record.setActivityType(activityType);
        record.setUserId(userId);
        Example<TurnTableRecord> example = Example.of(record);
        List<TurnTableRecord> all = turnTableRecordRepository.findAll(example);
        return all;
    }

    /**
     * 管理后台获取所有刮刮卡活动列表
     * @param request
     * @return
     */
    public PageDTO findAllActivityByPage(TurnTableRequest request){
        Sort sort = new Sort(Sort.Direction.DESC,"createTime");
        Pageable pageable = PageRequest.of(request.getPage(),request.getSize(),sort);

        Page<TurnTable> all = turnTableRepository.findAll((Specification<TurnTable>) (root, query, criteriaBuilder)->{
            Predicate conditions = criteriaBuilder.conjunction();
            conditions = criteriaBuilder.and(criteriaBuilder.notEqual(root.get("status").as(Integer.class),2));
            if(StringUtils.isNotEmpty(request.getKeyword())){
                Predicate p1 = criteriaBuilder.like(root.get("name").as(String.class), "%" + request.getKeyword() + "%");
                conditions = criteriaBuilder.and(conditions,p1);
            }
            return query.where(conditions).getRestriction();
        }, pageable);
        PageDTO<TurnTable> pageDTO = new PageDTO<>();
        pageDTO.setTotal(all.getTotalElements());
        pageDTO.setList(all.getContent());
        pageDTO.setTotalPage(all.getTotalPages());
        pageDTO.setPage(request.getPage());
        pageDTO.setPageSize(request.getSize());
        pageDTO.setKeyword(request.getKeyword());
        return pageDTO;
    }

    /**
     * 后台获取活动所有奖项
     * @param request
     * @return
     */
    public PageDTO getAllGifts(TurnTableRequest request){
        Sort sort = new Sort(Sort.Direction.DESC,"createTime");
        Pageable pageable = PageRequest.of(request.getPage(),request.getSize(),sort);

        Page<TurnTableGift> all = turnTableGiftRepository.findAll((Specification<TurnTableGift>) (root, query, criteriaBuilder)->{
            Predicate conditions = criteriaBuilder.conjunction();
            conditions = criteriaBuilder.and(criteriaBuilder.equal(root.get("activityId").as(Long.class),request.getId()));
            conditions = criteriaBuilder.and(conditions,criteriaBuilder.notEqual(root.get("status").as(Integer.class),2));
            return query.where(conditions).getRestriction();
        }, pageable);
        PageDTO<TurnTableGift> pageDTO = new PageDTO<>();
        pageDTO.setTotal(all.getTotalElements());
        pageDTO.setList(all.getContent());
        pageDTO.setTotalPage(all.getTotalPages());
        pageDTO.setPage(request.getPage());
        pageDTO.setPageSize(request.getSize());
        pageDTO.setKeyword(request.getKeyword());
        return pageDTO;
    }


    /**
     * 管理后台获取所有刮刮卡活动列表
     * @param request
     * @return
     */
    public PageDTO findAllRecordByPage(TurnTableRequest request){
        Sort sort = new Sort(Sort.Direction.DESC,"createTime");
        Pageable pageable = PageRequest.of(request.getPage(),request.getSize(),sort);

        Page<TurnTableRecord> all = turnTableRecordRepository.findAll((Specification<TurnTableRecord>) (root, query, criteriaBuilder)->{
            Predicate conditions = criteriaBuilder.conjunction();
            conditions = criteriaBuilder.and(criteriaBuilder.equal(root.get("activityId").as(Long.class),request.getActivityId()));
            conditions = criteriaBuilder.and(conditions,criteriaBuilder.equal(root.get("activityType").as(Integer.class),1));
//            if(StringUtils.isNotEmpty(request.getKeyword())){
//                Predicate p1 = criteriaBuilder.like(root.get("code").as(String.class), "%" + request.getKeyword() + "%");
//                conditions = criteriaBuilder.and(conditions,p1);
//            }
            return query.where(conditions).getRestriction();
        }, pageable);
        log.info(JSON.toJSONString(all));
        PageDTO<TurnTableRecord> pageDTO = new PageDTO<>();
        pageDTO.setTotal(all.getTotalElements());

        List<TurnTableRecord> list = all.getContent();
        for (int i = 0; i < list.size(); i++) {
            IdDTO idDTO = new IdDTO();
            List<String> ids = new LinkedList<>();
            ids.add(list.get(i).getUserId());
            idDTO.setForeignKeyIds(ids);

            UserInfoDTO userInfoDTO = restTemplate.postForObject("http://QUANQUAN-USER/user/query_by_id_list", idDTO, UserInfoDTO.class);
            if(null == userInfoDTO || userInfoDTO.getUserDTOS().size() < 1){
                continue;
            }
            UserDTO userDTO = userInfoDTO.getUserDTOS().get(0);
            if(null == userDTO){
                continue;
            }
            list.get(i).setUserPhone(userDTO.getPhone());
            log.info(list.get(i).getUserPhone());

            if(list.get(i).getGiftType() == 1){
                try {
                    CouponDTO couponDTO = couponService.queryDetailsById(list.get(i).getCouponId());
                    if(null != couponDTO){
                        list.get(i).setCouponName(couponDTO.getName());
                    }
                }catch (Exception e){
                    log.info("优惠券详情查询失败");
                }
            }
        }

        pageDTO.setList(list);
        pageDTO.setTotalPage(all.getTotalPages());
        pageDTO.setPage(request.getPage());
        pageDTO.setPageSize(request.getSize());
        pageDTO.setKeyword(request.getKeyword());
        return pageDTO;
    }
}
